package sample.plugin;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.logging.SystemStreamLog;
import org.apache.maven.plugins.surefire.report.ReportTestCase;
import org.apache.maven.plugins.surefire.report.ReportTestSuite;
import org.apache.poi.ss.usermodel.Workbook;
import org.netbeans.nbbuild.VerifyClassLinkageForTest02;

import sample.plugin.model.CaseIntroDto;
import sample.plugin.model.CaseResult;
import sample.plugin.model.SuiteDto;
import net.sf.jxls.transformer.XLSTransformer;

public class XlsTest {
	private Log log;
	public XlsTest (final Log log){
		this.log = log;
	}

	public Log getLog() {
		if (log == null) {
			log = new SystemStreamLog();
		}
		return log;
	}

	public static void main(String[] args) {
		final SuiteDto suiteDto = new SuiteDto();
		suiteDto.setTestItemNo("ITS_RL_01310");
		suiteDto.setComposeDate("2012/07/06");
		suiteDto.setTestItemName("遷入登記");
		suiteDto.setRequireUnitNo("FR_RL_01310");
		suiteDto.setAuthor("張淑誼");

		final CaseIntroDto sampleDto = new CaseIntroDto();
		sampleDto.setAuthor("張淑誼");
		sampleDto.setCaseIntro("當事人為虛報遷徙人口，資料驗證失敗");
		sampleDto.setCaseNo("TC_ITS_RL_01310_001");
		sampleDto.setComposeDate("2012/07/06");
		sampleDto.setExpect("系統顯示「TX-6139-E虛報遷徙人口必須撤銷遷徙後才可遷徙」錯誤訊息");
		sampleDto
				.setPrerequisite("戶籍員登入系統並進入「戶籍查詢/登記/文件核發」作業畫面，輸入當事人統號、第一位申請人統號後，點選「遷入登記」連結，進入「遷入登記」作業畫面");
		sampleDto.setRequireUnitNo("FR_RL_01310");
		sampleDto.setTestItemName("遷入登記");
		sampleDto.setTestItemNo("ITS_RL_01310");
		sampleDto
				.setTestSteps("1.戶籍員輸入「當事人資料」、「其他申請資料」、「原住地資料」\r2.戶籍員按下「資料驗證」按鈕");

		suiteDto.getCaseList().add(sampleDto);

		// 假設情境為
		final File outputFile = new File("/home/weblogic/Desktop/test.xls");

		new XlsTest (new SystemStreamLog()) . outputFile(suiteDto,outputFile);

	}

	private File getTargetDirectory(File file){
		if(file == null ){
			return null;
		}
		final	File parentFile = file.getParentFile();
		String parent = parentFile.getName();
		if("target".equals(parent)){
			return parentFile;
		}else {
			return getTargetDirectory(file);
		}
	}
	public void test(final List<ReportTestSuite> testSuites ,File testOutputDirectory) {
		final File tragetDirectory = getTargetDirectory(testOutputDirectory);
		getLog().info("----------tragetDirectory: " + tragetDirectory.getAbsolutePath());
		if (testSuites != null) {
			for (final ReportTestSuite suite : testSuites) {
				getLog().info("----------fullClassName: " + suite.getFullClassName());
				//輸出檔名來源
				String fileName =testOutputDirectory.getAbsolutePath() +File.separator + 
						StringUtils.replace(suite.getFullClassName(), ".", File.separator)+".class";
				final VerifyClassLinkageForTest02 v2 = new VerifyClassLinkageForTest02();
				getLog().info("--------fileName: " + fileName);
				InputStream is = null; 
				List<CaseIntroDto>  caseIntroDtoList =null ;
				try {
					is = new FileInputStream(fileName) ;
					byte[] data = IOUtils.toByteArray(is );
					List<String> src =  v2.readByteCode(data);
					caseIntroDtoList = new ExtractByByte().convert(src);
					
				} catch (FileNotFoundException e) {
					getLog().error(e.getMessage() ,e );
				} catch (IOException e) {
					getLog().error(e.getMessage() ,e );
				}finally{
					if(is != null){
						try {
							is.close();
						} catch (IOException e) {
							getLog().error(e.getMessage() ,e );
						}
					}
				}
				getLog().info("--------suite.getName(): " + suite.getName());

				getLog().info("---------umberOfTests: " + suite.getNumberOfTests());

				getLog().info("---------numberOfErrors: " + suite.getNumberOfErrors());

				getLog().info(
						"------------numberOfFailures: " + suite.getNumberOfFailures());

				getLog().info("----------NumberOfSkipped: " + suite.getNumberOfSkipped());
			
				final List<ReportTestCase> testCases = suite.getTestCases();
				final SuiteDto suiteDto = new SuiteDto();
				
				if(testCases != null ){
					if(CollectionUtils.isNotEmpty(caseIntroDtoList)){						
						suiteDto.setComposeDate(caseIntroDtoList.get(0).getComposeDate());
						suiteDto.setTestItemName(caseIntroDtoList.get(0).getTestItemName());
						suiteDto.setRequireUnitNo(caseIntroDtoList.get(0).getRequireUnitNo());
						suiteDto.setAuthor(caseIntroDtoList.get(0).getAuthor());
						suiteDto.setCaseList(caseIntroDtoList);						
					}
					
					for(int i =0 ; i < testCases.size() ; ++i ){					 
						final ReportTestCase tc  = testCases.get(i);
						
						getLog().info("----------name: " + tc.getName() );
						getLog().info("----------time : " + tc.getTime() );
						final Map<String, Object> mapData = tc.getFailure();
						
						if(mapData != null ){
							final 	Set<Entry<String, Object>> entrySet = mapData.entrySet() ;
							for(Entry<String, Object> unit :  entrySet ) {
								getLog().info("----------key: " + unit.getKey() );
								getLog().info("----------value : " + unit.getValue());
							}
						}
						
						
						CaseResult result = new CaseResult();
						if(MapUtils.isEmpty(mapData)){
							result.setTestResult("通過");
						}else{
							result.setTestResult("不通過");
						}
						caseIntroDtoList.get(i).setResult(result);
					}
				}
				final File outputFile =new File( tragetDirectory , suite.getFullClassName()+".xls");
				
				outputFile(suiteDto , outputFile);
			}
		}
	}

	public  void outputFile(final SuiteDto suiteDto ,final File outputFile  ) {
		final Map<String, Object> beans = new HashMap<String, Object>();
		InputStream is = null;
		beans.put("suiteDto", suiteDto);
		final XLSTransformer transformer = new XLSTransformer();
		try {
			is = XlsTest.class.getResourceAsStream("template01.xls");
			final Workbook document = transformer.transformXLS(is, beans);
			
			writeWorkbookOut(outputFile, document);
		} catch (Exception e) {
//			getLog().error(e.getMessage() ,e );
			e.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
//					getLog().error(e.getMessage(), e);
					e.printStackTrace();
				}
			}
		}
	}

	public  void writeWorkbookOut(File output, Workbook document)
			throws IOException {
		final ByteArrayOutputStream ostream = new ByteArrayOutputStream();
		final FileOutputStream out = new FileOutputStream(output);
		try {
			document.write(ostream);
			out.write(ostream.toByteArray());
		} finally {
			try {
				out.close();
			} catch (IOException e) {
//				getLog().error(e.getMessage(), e);
				e.printStackTrace();
			}
			try {
				ostream.close();
			} catch (IOException e) {
//				getLog().error(e.getMessage(), e);
				e.printStackTrace();
			}
		}
	}

}
